/*++

Copyright (c) 2007  Microsoft Corporation 

Filename: 

    MachineSelector.cs

Abstract: 

    Form to select the machines to monitor
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Collections;
using Visio = Microsoft.Office.Interop.Visio;
using Excel = Microsoft.Office.Interop.Excel;
using System.Data.OleDb;
using System.Threading;
using System.Management;
using System.Globalization;
using AddIn.Windows.Forms;
using Microsoft.EnterpriseManagement;
using System.Collections.ObjectModel;
using Microsoft.EnterpriseManagement.Configuration;
using Microsoft.EnterpriseManagement.Monitoring;
using Microsoft.EnterpriseManagement.Common;

namespace NRTMAddIn
{
    public partial class MachineSelector : AddIn.Windows.Forms.InteriorWizardPage
    {
        #region Variables
        private ArrayList[] MachineAr;
        private ArrayList ShapeList;
        private Thread NRTMDiagramThread;

        #endregion

        #region Construction
        /// <summary>
        /// Constructor
        /// </summary>
        public MachineSelector()
        {
            InitializeComponent();
            this.chkAll.Text = Global.GetResourceString("CheckUncheckBox_Text");
            this.m_subtitleLabel.Text = Global.GetResourceString("MachineSelectorSubTitle_Text");
            this.titleLabel.Text = Global.GetResourceString("MachineSelectorTitle_Text");
        }
        #endregion

        #region Methods
        /// <summary>
       /// On Form Active
       /// </summary>
       /// <returns></returns>
        protected override bool OnSetActive()
        {
            if (!base.OnSetActive())
                return false;

            try
            {  
                //Input OpsMgr
                if (Global.IPOption == Global.InputDataOption.SCOM)
                {
                    FillListBoxFromSCOMSDK();
                }
                //Input Excel
                else if (Global.IPOption == Global.InputDataOption.Excel)
                {
                    FillListBoxFromExcel();
                }
                //Input ActivePage    
                else if (Global.IPOption == Global.InputDataOption.ActivePage)
                {
                    FillListBoxFromActivePage();
                }

                //Enable the finish button only when list of machines is not empty
                if (clstMachineList.Items.Count == 0)
                {
                    return false;
                }
                else
                {
                    // Enable both the Back and Finish (enabled/disabled) buttons on this page    
                    Wizard.SetWizardButtons(WizardButtons.Back | WizardButtons.Finish);
                    return true;
                }
            }
            catch (NrtmException ex)
            {
                NrtmException.HandleExceptions(Global.GetResourceString("Exception_MsgBox_Caption"),
                            Global.GetResourceString("Exception_UsrMsg"), ex.InnerException);
                return false;
            }
            catch (Exception ex)
            {
                NrtmException.HandleExceptions(Global.GetResourceString("Exception_MsgBox_Caption"),
                            Global.GetResourceString("Exception_UsrMsg"), ex);

                return false;
            }
        }

        /// <summary>
        /// On Finish Clicked
        /// </summary>
        /// <returns></returns>
        protected override bool OnWizardFinish()
        {
            DiagramGenerator dg = null;
            int ServerCtr = 0;
            try
            {
                if (clstMachineList.CheckedItems.Count <= 0)
                {
                    MessageBox.Show(Global.GetResourceString("MachineSelectMsg"),
                    Global.GetResourceString("Document_MsgBox_Title"),
                    MessageBoxButtons.OK, MessageBoxIcon.Information,
                    MessageBoxDefaultButton.Button1);
                    return false;
                }
                for (int i = 0; i < clstMachineList.Items.Count; i++)
                {
                    //Update the machine array based on checked status
                    if (clstMachineList.GetItemChecked(i))
                    {
                        MachineAr[0][ServerCtr] = true;
                        ServerCtr++;
                        if (Global.IPOption == Global.InputDataOption.ActivePage)
                        {
                            //Set configure property to TRUE
                            Visio.Shape currShape = (Visio.Shape)ShapeList[i];
                            if (ConfigureServerShape.ShapePropertyExist(currShape, "User.NRTMConfig"))
                            {
                                //If User.NRTMConfig property exist set it to true
                                currShape.get_Cells("User.NRTMConfig.Value").FormulaU = "TRUE";
                            }
                            else
                            {
                                //User.NRTMConfig not found. Configure the shape for NRTM monitoring
                                ConfigureServerShape.VisioApp_ShapeAdded(currShape);
                            }
                        }
                    }
                    else
                    {
                        //Delete the entry from the machine array
                        MachineAr[0].RemoveAt(ServerCtr);
                        MachineAr[1].RemoveAt(ServerCtr);
                        MachineAr[2].RemoveAt(ServerCtr);
                        if (Global.IPOption == Global.InputDataOption.ActivePage)
                        {
                            //Set configure property to FALSE
                            Visio.Shape currShape = (Visio.Shape)ShapeList[i];
                            if (ConfigureServerShape.ShapePropertyExist(currShape, "User.NRTMConfig"))
                            {
                                //If User.NRTMConfig property exist set it to false
                                currShape.get_Cells("User.NRTMConfig.Value").FormulaU = "FALSE";
                            }
                        }
                    }
                }

                if (Global.IPOption == Global.InputDataOption.SCOM ||
                    Global.IPOption == Global.InputDataOption.Excel)
                {
                    NRTMDiagramThread = null;
                    dg = new DiagramGenerator();
                    NRTMDiagramThread = new Thread(new ParameterizedThreadStart(dg.CreateDocument));

                    if (NRTMDiagramThread != null)
                    {
                        NRTMDiagramThread.Name = "NRTMDiagramGenerator";
                        NRTMDiagramThread.Start(MachineAr);
                    }
                }
                return true;
            }
            catch (NrtmException ex)
            {
                //To catch and display exceptions from sub functions
                NrtmException.HandleExceptions(Global.GetResourceString("Exception_MsgBox_Caption"),
                            Global.GetResourceString("Exception_UsrMsg"), ex.InnerException);

                return false;
            }
            catch (Exception ex)
            {
                //To catch exceptions from current functions
                NrtmException.HandleExceptions(Global.GetResourceString("Exception_MsgBox_Caption"),
                            Global.GetResourceString("Exception_UsrMsg"), ex);

                return false;
            }
        }

        /// <summary>
        /// On Back clicked
        /// </summary>
        /// <returns></returns>
        protected override string OnWizardBack()
        {
            if (Global.IPOption == Global.InputDataOption.SCOM)
            {
                return "OpsMgrConnection";
            }
            else
            {
            return "DataSelector";
            }
        }

        /// <summary>
        /// Check or uncheck all the machines
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chkAll_CheckedChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < clstMachineList.Items.Count; i++)
            {
                clstMachineList.SetItemChecked(i, chkAll.Checked);
            }

        }

        // <summary>
        /// Fill the machine list from SCOM SDK
        /// </summary>
        private void FillListBoxFromSCOMSDK()
        {
            int ctr = 0;
            string ipAddress = null;

            // Define the server that you want to connect to.
            string serverName = Global.ServerName;

            ManagementGroup mg = null;

            ReadOnlyCollection<MonitoringObject> monitoringObjects_Computers = null;

            try
            {
                mg = ManagementGroup.Connect(serverName);

                MonitoringClass monitoringClass_Machine;

                monitoringClass_Machine = mg.GetMonitoringClass(SystemMonitoringClass.Computer);

                monitoringObjects_Computers = mg.GetMonitoringObjects(monitoringClass_Machine);

                ReadOnlyCollection<MonitoringClassProperty> properties1;

                if (MachineAr != null)
                {
                    MachineAr[0] = null;
                    MachineAr[1] = null;
                    MachineAr[2] = null;
                    MachineAr = null;
                    clstMachineList.Items.Clear();
                }
                MachineAr = new ArrayList[3];

                MachineAr[0] = new ArrayList();
                MachineAr[1] = new ArrayList();
                MachineAr[2] = new ArrayList();


                foreach (MonitoringObject nextMachine in monitoringObjects_Computers)
                {
                    ipAddress = String.Empty;
                    if (nextMachine.HealthState != HealthState.Uninitialized)
                    {
                        //Get all monitoring properties
                        properties1 = nextMachine.GetMonitoringProperties();

                        MachineAr[0].Add(false);

                        //properties1.
                        foreach (MonitoringClassProperty property in properties1)
                        {
                            if (property.DisplayName == "NetBIOS Computer Name")
                            {
                                MachineAr[1].Add(nextMachine.GetMonitoringPropertyValue(property).ToString());
                                //MachineAr[1].Add(nextMachine.GetMonitoringPropertyValue((MonitoringClassProperty)("NetBIOS Computer Name")).ToString());
                            }
                            if (property.DisplayName == "IP Address")
                            {
                                ipAddress = nextMachine.GetMonitoringPropertyValue(property).ToString();
                                if (ipAddress.Contains(","))
                                {
                                    MachineAr[2].Add(ipAddress.Substring(0, ipAddress.IndexOf(',')));
                                }
                                else
                                {
                                    MachineAr[2].Add(ipAddress);
                                }
                            }
                        }

                        clstMachineList.Items.Add(MachineAr[1][ctr], CheckState.Unchecked);
                        ctr++;
                    }
                }

            }
            catch (ServerDisconnectedException ex)
            {
                //Exception from current function
                throw new NrtmException("Perform Monitoring using SCOM SDK", ex);
            }
            catch (System.Threading.ThreadAbortException)
            {
                //Ignore thread abort exception
            }
            catch (NrtmException ex)
            {
                //Exception from sub function. Pass on to entry point
                throw new NrtmException("Perform Monitoring using SCOM SDK", ex.InnerException);
            }
            catch (Exception ex)
            {
                //Exception from current function
                throw new NrtmException("Perform Monitoring using SCOM SDK", ex);
            }
            
        }

        

        /// <summary>
        /// Fill the machine list box from the shapes on the active page
        /// Shapes should have either IP address or network name assigned
        /// </summary>
        private void FillListBoxFromActivePage()
        {
            int ctr = 0;
            try
            {

                this.FindForm().Cursor = Cursors.WaitCursor;

                if (MachineAr != null)
                {
                    MachineAr[0] = null;
                    MachineAr[1] = null;
                    MachineAr[2] = null;
                    MachineAr = null;
                    ShapeList = null;
                    clstMachineList.Items.Clear();
                }
                if (Global.VisioApp.ActiveDocument == null)
                {
                    MessageBox.Show(Global.GetResourceString("MachineSelect_Page_Text"), 
                        Global.GetResourceString("NRTM_MachineSelect_MsgBox_Title"),
                        MessageBoxButtons.OK, MessageBoxIcon.Error,
                        MessageBoxDefaultButton.Button1);
                }

                //Get the Document class object reference
                Document nrtmDoc = Application.GetDocumentObject(Global.VisioApp.ActiveDocument);

                MachineAr = new ArrayList[3];
                MachineAr[0] = new ArrayList();
                MachineAr[1] = new ArrayList();
                MachineAr[2] = new ArrayList();
                ShapeList = new ArrayList();

                ctr = 0;
                foreach (Visio.Page currPage in nrtmDoc.VisioDocument.Pages)
                {
                    foreach (Visio.Shape shape in currPage.Shapes)
                    {
                        //Check for server shapes with type = 2
                        if (ConfigureServerShape.ValidNetworkShape(shape))
                        {
                            Visio.Cell cellNtwrkName = shape.get_Cells("Prop.NetworkName.Value");
                            Visio.Cell cellIpAddress = shape.get_Cells("Prop.IPAddress.Value");

                            string SerName = cellNtwrkName.FormulaU.Replace("\"", "").Trim().ToUpper(CultureInfo.CurrentCulture);
                            string IPAddr = cellIpAddress.FormulaU.Replace("\"", "").Trim().ToUpper(CultureInfo.CurrentCulture);

                            //Check if NRTM configured with server name and ip address
                            if (!string.IsNullOrEmpty(SerName) || !string.IsNullOrEmpty(IPAddr))
                            {

                                //Add to array list
                                MachineAr[0].Add(false);
                                MachineAr[1].Add(SerName);
                                MachineAr[2].Add(IPAddr);

                                //Add to checked list box
                                //In case of invlaid IP address no server name will exisit. Add IP address to the list
                                if (!string.IsNullOrEmpty(SerName))
                                {
                                    clstMachineList.Items.Add(SerName, CheckState.Unchecked);
                                }
                                else
                                {
                                    clstMachineList.Items.Add(IPAddr, CheckState.Unchecked);
                                }

                                //Add shape reference to ShapeList to be used in final button click event to set NRTMConfig property.
                                ShapeList.Add(shape);

                                ctr++;
                            }
                        }

                    }
                }

                if (ctr == 0)
                {
                    MessageBox.Show(Global.GetResourceString("NRTM_Config_Text"),
                        Global.GetResourceString("NRTM_MachineSelect_MsgBox_Title"),
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information,
                        MessageBoxDefaultButton.Button1);
                }
            }
            catch (NrtmException ex)
            {
                //Exception from sub function. Pass on to entry point
                throw new NrtmException("Fill ListBox From ActivePage", ex.InnerException);
            }
            catch (Exception ex)
            {
                //Exception from current function
                throw new NrtmException("Fill ListBox From ActivePage", ex);
            }
            finally
            {
                this.FindForm().Cursor = Cursors.Default;
            }

        }

        /// <summary>
        /// Fill the list box with the server name from the excel sheet
        /// </summary>
        private void FillListBoxFromExcel()
        {
            int ctr = 0;
            Excel.Application excelApplication = null;
            Excel.Workbook theWorkbook = null;
            Excel.Sheets sheets = null;
            Excel.Worksheet worksheet = null;

            try
            {
                this.FindForm().Cursor = Cursors.WaitCursor;

                excelApplication = new Excel.ApplicationClass();

                if (MachineAr != null)
                {
                    //Clear old data
                    MachineAr[0] = null;
                    MachineAr[1] = null;
                    MachineAr[2] = null;
                    MachineAr = null;
                    clstMachineList.Items.Clear();
                }
                MachineAr = new ArrayList[3];

                MachineAr[0] = new ArrayList();
                MachineAr[1] = new ArrayList();
                MachineAr[2] = new ArrayList();

                // call to Open a Workbook in Excel 
                theWorkbook = excelApplication.Workbooks.Open(Global.ExcelFileName, 0, true, 5,
                string.Empty, string.Empty, true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, true, false);
                // get the collection of sheets in the workbook
                sheets = theWorkbook.Worksheets;
                // get the first and only worksheet from the collection of worksheets
                worksheet = (Excel.Worksheet)sheets.get_Item(1);

                bool FirstRow = true;
                int RowCtr = 1;
                bool InvalidExcel = false;
                while (true)
                {
                    Excel.Range range = worksheet.get_Range("A" + RowCtr.ToString(CultureInfo.InvariantCulture), "B" + RowCtr.ToString(CultureInfo.InvariantCulture));
                    System.Array myvalues = (System.Array)range.Cells.Value2;
                    string[] strArray = ConvertToStringArray(myvalues);
                    string networkName = strArray[0];
                    string ipAddress = strArray[1];
                    if (!string.IsNullOrEmpty(networkName) || !string.IsNullOrEmpty(ipAddress))
                    {
                        if (FirstRow &&
                            (string.Compare(networkName, Global.GetResourceString("Excel_Import_ColText1")) != 0 ||
                             string.Compare(ipAddress, Global.GetResourceString("Excel_Import_ColText2")) != 0))
                        {
                            MessageBox.Show(Global.GetResourceString("Excel_InCorrectFormat_Text"),
                                Global.GetResourceString("NRTM_MachineSelect_MsgBox_Title"),
                                MessageBoxButtons.OK, MessageBoxIcon.Error,
                                MessageBoxDefaultButton.Button1);
                                //MessageBoxOptions.DefaultDesktopOnly);
                            InvalidExcel = true;
                            
                            //this.InvokeOnClick(null, EventArgs.Empty);
                            break;
                        }
                        else if (FirstRow &&
                            string.Compare(networkName, Global.GetResourceString("Excel_Import_ColText1")) == 0 &&
                            string.Compare(ipAddress, Global.GetResourceString("Excel_Import_ColText2")) == 0)
                        {
                            FirstRow = false;
                        }
                        else if (!FirstRow)
                        {
                            //Add to array list
                            MachineAr[0].Add(false);
                            MachineAr[1].Add(networkName);
                            MachineAr[2].Add(ipAddress);

                            //Add to checked list box
                            //In case of invlaid IP address no server name will exisit. Add IP address to the list
                            if (!string.IsNullOrEmpty(networkName))
                            {
                                clstMachineList.Items.Add(networkName, CheckState.Unchecked);
                            }
                            else
                            {
                                clstMachineList.Items.Add(ipAddress, CheckState.Unchecked);
                            }
                            ctr++;
                        }
                    }
                    else
                    {
                        //break on first empty row in the excel
                        break;
                    }
                    RowCtr++;
                }
                if (ctr == 0 && !InvalidExcel)
                {
                    MessageBox.Show(Global.GetResourceString("Excel_Blank_Text"),
                        Global.GetResourceString("NRTM_MachineSelect_MsgBox_Title"),
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information,
                        MessageBoxDefaultButton.Button1);
                }

            }
            catch (NrtmException ex)
            {
                //Exception from sub function. Pass on to entry point
                throw new NrtmException("Fill List Box From Excel", ex.InnerException);
            }
            catch (Exception ex)
            {
                //Exception from current function
                throw new NrtmException("Fill List Box From Excel", ex);
            }
            finally
            {
                this.FindForm().Cursor = Cursors.Default;
                if (excelApplication != null)
                {
                    if (theWorkbook != null)
                    {
                        theWorkbook.Close(false, "", false);
                        theWorkbook = null;
                    }

                    excelApplication.Quit();
                }
            }
        }

        /// <summary>
        /// Convert Array to String Array
        /// </summary>
        /// <param name="values">Array object</param>
        /// <returns>String Array</returns>
        private static string[] ConvertToStringArray(System.Array values)
        {
            // create a new string array
            string[] theArray = new string[values.Length];
            // loop through the 2-D System.Array and populate the 1-D String Array
            for (int i = 1; i <= values.Length; i++)
            {
                if (values.GetValue(1, i) == null)
                    theArray[i - 1] = string.Empty;
                else
                    theArray[i - 1] = values.GetValue(1, i).ToString().ToUpper(CultureInfo.CurrentCulture);
            }
            return theArray;
        }
        #endregion
    }
}

